package com.xxxx.car.flow.controller;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import java.util.List;
import javax.servlet.http.HttpServletResponse;

import com.xxxx.car.flow.vo.BpmnInfoVo;
import org.apache.commons.io.IOUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StreamUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.xxxx.car.common.annotation.Log;
import com.xxxx.car.common.core.controller.BaseController;
import com.xxxx.car.common.core.domain.AjaxResult;
import com.xxxx.car.common.enums.BusinessType;
import com.xxxx.car.flow.domain.BpmnInfo;
import com.xxxx.car.flow.service.IBpmnInfoService;
import com.xxxx.car.common.utils.poi.ExcelUtil;
import com.xxxx.car.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 流程定义Controller
 * 
 * @author Huang
 * @date 2024-09-05
 */
@Validated
@RestController
@RequestMapping("/flow/bpmnInfo")
public class BpmnInfoController extends BaseController
{
    @Autowired
    private IBpmnInfoService bpmnInfoService;

    /**
     * 查询流程定义列表
     */
    @PreAuthorize("@ss.hasPermi('flow:bpmnInfo:list')")
    @GetMapping("/list")
    public TableDataInfo list(BpmnInfo bpmnInfo)
    {
        startPage();
        List<BpmnInfo> list = bpmnInfoService.selectBpmnInfoList(bpmnInfo);
        return getDataTable(list);
    }

    /**
     * 导出流程定义列表
     */
    @PreAuthorize("@ss.hasPermi('flow:bpmnInfo:export')")
    @Log(title = "流程定义", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BpmnInfo bpmnInfo)
    {
        List<BpmnInfo> list = bpmnInfoService.selectBpmnInfoList(bpmnInfo);
        ExcelUtil<BpmnInfo> util = new ExcelUtil<BpmnInfo>(BpmnInfo.class);
        util.exportExcel(response, list, "流程定义数据");
    }

    /**
     * 获取流程定义详细信息
     */
    @PreAuthorize("@ss.hasPermi('flow:bpmnInfo:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(bpmnInfoService.selectBpmnInfoById(id));
    }

    /**
     * 获取流程定义详细信息
     */
    @PreAuthorize("@ss.hasPermi('flow:bpmnInfo:query')")
    @GetMapping(value = "/{id}/{type}")
    public void getBpmnFile(@PathVariable("id") Long id,@PathVariable("type") String type,HttpServletResponse response) throws IOException {
        InputStream bpmnFile = bpmnInfoService.selectBpmnInfoFile(id,type);
        if(bpmnFile == null){
            return;
        }
        /*
        * 如果在 try 块内部声明 out，
        * 那么一旦发生异常，finally 块中的 out.close() 调用可能会抛出 NullPointerException，因为 out 可能没有被成功初始化。
        * 通过在外部声明，可以确保 finally 块中的 out.close() 总是有一个有效的对象引用
        * */
        ByteArrayOutputStream out = null;
        try {
            if("image".equals(type)){
                 out = new ByteArrayOutputStream();
                StreamUtils.copy(bpmnFile,out);
                byte[] bytes = out.toByteArray();
                String encode = Base64.getEncoder().encodeToString(bytes);
                String prefix = "data:image/png;base64,";
                String content = prefix + encode;
                response.getWriter().write(content);
                return;
            }
            IOUtils.copy(bpmnFile,response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            bpmnFile.close();
            if(out != null){
                out.close();
            }
        }

    }


    /**
     * 新增流程定义
     */
    @PreAuthorize("@ss.hasPermi('flow:bpmnInfo:deploy')")
    @Log(title = "流程定义部署", businessType = BusinessType.INSERT)
    @PostMapping("/deploy")
    public AjaxResult deploy(BpmnInfoVo bpmnInfoVo)
    {
        return toAjax(bpmnInfoService.deployBpmnInfo(bpmnInfoVo));
    }

    /**
     * 修改流程定义
     */
    @PreAuthorize("@ss.hasPermi('flow:bpmnInfo:edit')")
    @Log(title = "流程定义", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(BpmnInfo bpmnInfo)
    {
        return toAjax(bpmnInfoService.updateBpmnInfo(bpmnInfo));
    }

    /**
     * 删除流程定义
     */
    @PreAuthorize("@ss.hasPermi('flow:bpmnInfo:remove')")
    @Log(title = "流程定义", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(bpmnInfoService.deleteBpmnInfoByIds(ids));
    }
}
